/**
 * Copyright 2004 - 2007 Blue Bamboo International Inc. 
 *           All rights reserved.
 *
 *
 * Blue Bamboo PROPRIETARY/CONFIDENTIAL.
 *
 */

package com.bluebamboo.bluetools.pingpang;

import java.util.HashMap;
import java.util.Map;

import org.apache.mina.core.service.IoHandler;
import org.eclipse.core.runtime.Assert;

import com.bluebamboo.bluetools.pingpang.bean.ConnectionBean;
import com.bluebamboo.bluetools.pingpang.bean.ConnectionBeanManager;
import com.bluebamboo.bluetools.pingpang.connection.IConnectionHandler;
import com.bluebamboo.bluetools.pingpang.connection.IConnectionHandler.Status;

/**
 * DOCME
 * 
 * @author tanxuqing
 * @date Sep 13, 2009
 * @since
 */
public class ConnectionManager {

	private static final ConnectionManager singleton = new ConnectionManager();
	private ConnectionBeanManager beanManager;

	/**
	 * connection name maps to connection handler
	 */
	private HashMap<String, IConnectionHandler> connectionHandlers;

	public static ConnectionManager getInstance() {
		return singleton;
	}

	private ConnectionManager() {
		connectionHandlers = new HashMap<String, IConnectionHandler>();
		beanManager = ConnectionBeanManager.getInstance();
	}

	/**
	 * Connect with specified <code>ioHandler</code>
	 * 
	 * @param connectionName
	 * @param ioHandler
	 * @throws Exception
	 */
	public void open(ConnectionBean connBean, IoHandler ioHandler) throws Exception {
		open(connBean.getName(), ioHandler);
	}

	/**
	 * Connect with specified <code>ioHandler</code>
	 * 
	 * @param connectionName
	 * @param ioHandler
	 * @throws Exception
	 */
	public void open(String connectionName, IoHandler ioHandler) throws Exception {
		// check opened
		if (checkOpened(connectionName) == true) {
			throw new Exception("Connection " + connectionName + " has been opened!");
		}

		IConnectionHandler connHandler = getConnectionHandler(connectionName);
		connHandler.setIoHandler(ioHandler);
		connHandler.connect();
	}

	public void close(String connectionName) throws Exception {
		// check opened
		if (checkOpened(connectionName) == false) {
			throw new Exception("Connection " + connectionName + " has not yet opened!");
		}

		IConnectionHandler connHandler = connectionHandlers.get(connectionName);
		Assert.isNotNull(connHandler);

		// close
		connHandler.disconnect();
	}

	public void closeAll() throws Exception {
		for (Map.Entry<String, IConnectionHandler> entry : connectionHandlers.entrySet()) {
			IConnectionHandler connHandler = entry.getValue();
			if (connHandler.getStatus() == Status.CONNECTED) {
				connHandler.disconnect();
			}
		}
	}

	public boolean checkOpened(String connectionName) {
		IConnectionHandler connHandler = connectionHandlers.get(connectionName);
		if (connHandler == null) {
			return false;
		}

		return connHandler.getStatus() == Status.CONNECTED;
	}

	public IConnectionHandler getConnectionHandler(String connectionName) {
		IConnectionHandler connHandler = connectionHandlers.get(connectionName);
		// create connection handlder
		if (connHandler == null) {
			ConnectionBean connBean = beanManager.getBean(connectionName);
			connHandler = createConnectionHandler(connBean);
			connectionHandlers.put(connectionName, connHandler);
		}
		return connHandler;
	}

	public IConnectionHandler createConnectionHandler(ConnectionBean connectionBean) {
		return connectionBean.getConnectionHandler();
	}
}
